using System;
using System.Drawing;
using Framework.Interop;

namespace Framework
{
	///<summary>
	///</summary>
	public abstract class ShellIcon
	{
		///<summary>
		///</summary>
		///<param name="filename"></param>
		///<param name="index"></param>
		///<param name="cache"></param>
		///<param name="simulateDoc"></param>
		///<returns></returns>
		public static ShellIcon CreateFromFile(string filename, int index, bool cache, bool simulateDoc)
		{
		    ShellIcon icon = new FromFile(filename, index) {_dontCache = !cache, _simulateDoc = simulateDoc};
		    return icon;
		}

		///<summary>
		///</summary>
		///<param name="icon"></param>
		///<param name="cache"></param>
		///<param name="simulateDoc"></param>
		///<returns></returns>
		public static ShellIcon CreateFromIcon(Icon icon, bool cache, bool simulateDoc)
		{
		    ShellIcon si = new FromIcon(icon) {_dontCache = !cache, _simulateDoc = simulateDoc};
		    return si;
		}

		private bool _dontCache;
		private bool _simulateDoc;

		internal virtual ExtractIconFlags Flags
		{
			get
			{
				return
					(this._dontCache
						? ExtractIconFlags.DontCache
						: ExtractIconFlags.None) |
					(this._simulateDoc
						? ExtractIconFlags.SimulateDoc
						: ExtractIconFlags.None);
			}
		}

		internal sealed class FromFile : ShellIcon
		{
			private readonly string _filename;
			private readonly int _index;

			internal FromFile(string filename, int index)
			{
				if (filename == null)
				{
					throw new ArgumentNullException("filename");
				}

				this._filename = filename;
				this._index = index;
			}

			internal string Filename
			{
				get
				{
					return this._filename;
				}
			}
			
			internal int Index
			{
				get
				{
					return this._index;
				}
			}
		}

		internal sealed class FromIcon : ShellIcon
		{
			private readonly Icon _icon;

			internal FromIcon(Icon icon)
			{
				this._icon = icon;
			}

			internal Icon Icon
			{
				get
				{
					return this._icon;
				}
			}

			internal override ExtractIconFlags Flags
			{
				get
				{
					return base.Flags | ExtractIconFlags.NotFilename;
				}
			}
		}
	}
}
